/**
 * Copyright (c) 2011-2014, hubin (jobob@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.RowBounds;

/**
 * <p>
 * Mapper 继承该接口后，无需编写 mapper.xml 文件，即可获得CRUD功能
 * </p>
 * <p>
 * 这个 Mapper 支持 id 泛型
 * </p>
 * 
 * @author hubin
 * @Date 2016-01-23
 */
public interface BaseMapper<T, I> {

	/**
	 * <p>
	 * 插入一条记录
	 * </p>
	 * @param entity
	 * 				实体对象,当实体对象为null时,抛出MyBatisSystemException异常
	 * @return int 返回插入成功的记录数
	 */
	int insert( T entity );
	
	/**
	 * <p>
	 * 插入一条记录（选择字段， null 字段不插入）
	 * </p>
	 * @param entity
	 * 				实体对象,当实体对象为null时,抛出MyBatisSystemException异常
	 * @return int 返回插入成功的记录数
	 */
	int insertSelective( T entity );


	/**
	 * <p>
	 * 插入（批量）
	 * </p>
	 * @param entityList
	 * 				实体对象列表,
	 * 					实体对象列表为null时抛出：MyBatisSystemException;
	 * 					实体对象列表无数据时抛出:BadSqlGrammarException
	 * @return int 返回插入成功的记录数
	 */
	int insertBatch( List<T> entityList );


	/**
	 * <p>
	 * 根据 ID 删除
	 * </p>
	 * @param id
	 * 			主键ID,
	 * 				Id可以传入null值和""值,不会抛出异常
	 * @return int 返回删除成功的记录数
	 */
	int deleteById( I id );


	/**
	 * <p>
	 * 根据 entity 条件，删除记录
	 * </p>
	 * @param entity
	 * 				实体对象
	 * 					当实体对象为null时,抛出MyBatisSystemException异常
	 * @return int
	 */
	int deleteSelective( @Param("ew" ) T entity);


	/**
	 * <p>
	 * 删除（根据ID 批量删除）
	 * </p>
	 * @param idList
	 * 				主键ID列表,
	 * 					为null时抛出异常：MyBatisSystemException;
	 * 					主键列表无数据是抛出:BadSqlGrammarException
	 * @return int 返回删除成功的记录数
	 */
	int deleteBatchIds( List<I> idList );
	/**
	 * <p>
	 * 根据 ID修改
	 * </p>
	 * @param entity
	 * 				实体对象,对象为null时无法修改任何记录,但不报异常
	 * 				更新时不管entity的属性是否为null都会更新.
	 * @return 本次成功修改的记录数 
	 */
	int updateById( @Param("et" ) T entity);


	/**
	 * <p>
	 * 根据 ID选择性修改
	 * </p>
	 * @param entity
	 * 				实体对象,不允许为null,否则报异常MyBatisSystemException
	 * 				更新时选择性修改entity的属性不为null的属性才会更新.
	 * @return 本次成功修改的记录数 
	 */
	int updateSelectiveById( @Param("et" ) T entity);


	/**
	 * <p>
	 * 根据 whereEntity条件，更新记录
	 * </p>
	 * @param entity（可以为 null）
	 * 				实体对象,set中会包含所有的属性哪怕是为null的属性
	 * 				当实体对象为null时，相当于把每个属性都改为为null(主键除外)
	 * @param whereEntity（可以为 null）
	 * 				实体查询条件,where条件中只包含whereEntity中不为null的属性做条件
	 * 				whereEntity为null的时候表示不带任何条件
	 * @return 本次修改的记录数
	 */
	int update( @Param("et" ) T entity, @Param("ew") T whereEntity);


	/**
	 * <p>
	 * 根据 whereEntity条件，选择性更新记录
	 * </p>
	 * @param entity (不允许为null),为null时报异常:MyBatisSystemException
	 * 				      实体对象,set中只包含那些不为null的属性
	 * @param whereEntity（可以为 null）
	 * 				实体查询条件,where条件中只包含whereEntity中不为null的属性做条件
	 * 				whereEntity为null的时候表示不带任何条件
	 * @return 本次修改的记录数
	 */
	int updateSelective( @Param("et") T entity, @Param("ew") T whereEntity);


	/**
	 * <p>
	 * 根据ID选择性批量更新
	 * </p>
	 * @param entityList
	 * 				实体对象列表,其对象中为null的属性将不被更新
	 * 				实体对象列表为null时,报异常：MyBatisSystemException
	 * 				实体对象列表长度为0时,报异常:BadSqlGrammarException
	 * @return 本次修改的记录数
	 */
	int updateBatchById(List<T> entityList );


	/**
	 * <p>
	 * 根据 ID查询
	 * </p>
	 * @param id
	 * 			主键ID,可以为null或""
	 * @return T 找不到数据返回结果为null.
	 */
	T selectById(I id );


	/**
	 * <p>
	 * 查询(根据ID批量查询)
	 * </p>
	 * @param idList
	 * 				主键ID列表
	 * 				主键ID列表为null时,报异常:MyBatisSystemException
	 * 				主键ID列表长度为0时,报异常:BadSqlGrammarException
	 * @return List<T> 返回长度大于等于0的列表,当找不到数据时返回长度为0的列表.
	 */
	List<T> selectBatchIds( List<I> idList );
	
	/**
	 * <p>
	 * 根据 entity条件(不为null的属性)，查询一条记录
	 * </p>
	 * @param entity
	 * 				实体对象
	 * 				实体对象为null时,报异常:MyBatisSystemException
	 * @return T 返回找到的记录,找不到记录返回null,找到记录大于1条报异常MyBatisSystemException
	 */
	T selectOne( @Param("ew" ) T entity);
	
	
	/**
	 * <p>
	 * 根据 entity条件(不为null的属性)，查询总记录数
	 * </p>
	 * @param entity
	 * 				实体对象
	 * 				实体对象为null时,等同于不带where条件,返回所有记录数
	 * @return 返回满足条件的所有数据
	 */
	int selectCount( @Param("ew" ) T entity);


	/**
	 * <p>
	 * 根据 entity条件(只包含非null属性)，查询全部记录
	 * </p>
	 * <p>
	 * @param entityWrapper
	 * 					实体对象封装操作类（可以为 null=不带where条件）,
	 * 					包含排序的字段格式:new EntityWrapper<User>(u,"createtime desc");
	 * </p>
	 * @return List<T>  返回长度大于等于0的列表,当找不到数据时返回长度为0的列表.
	 */
	List<T> selectList( @Param("ew" ) EntityWrapper<T> entityWrapper);
	
	/**
	 * <p>
	 * 根据 entity条件(只包含非null属性)，查询全部记录(并翻页)
	 * </p>
	 * @param rowBounds 
	 * 					分页查询条件（可以为 RowBounds.DEFAULT）不允许为null,否则报异常MyBatisSystemException
	 * 					只能使用 RowBounds的子类：new Pagination(1,3)或 new Page<?>(1,3)
	 * @param entityWrapper
	 * 					实体对象封装操作类（可以为 null等同于不带where的查询）
	 * 					包含排序的字段格式:new EntityWrapper<User>(u,"createtime desc");
	 * @return List<T> 返回长度大于等于0的列表,当找不到数据时返回长度为0的列表.
	 */
	List<T> selectPage( RowBounds rowBounds, @Param("ew" ) EntityWrapper<T> entityWrapper);

}
